home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Design
/
WB Collection.iso
/
workbench werkzeuge
/
uhren & terminkalender
/
time
/
tolleuhr
/
tolleuhr_c
/
source
/
tolleuhr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-07
|
74KB
|
2,537 lines
#define VERSION "1.3 (17.11.95)"
/***************************************************************************
* * *
* Programm: TolleUhr * Version: s.o. *
* * *
****************************************************************************
* *
* Dieses Programm ist Public-Domain, d.h. wer immer Lust dazu hat, darf *
* dieses Programm kopieren, umschreiben, usw., vorausgesetzt: *
* *
* 1. Die Autorenliste bleibt voll erhalten. (auch in About-Requestern) *
* 2. Wer etwas am Programm verbricht, muß sich auch dazuschreiben. *
* *
* Es wird keine Haftung für Schäden irgendwelcher Art übernommen. *
* *
* Autoren: Matthias Fleischer Adlerstraße 30 7302 Ostfildern 2 *
* (fleischr@izfm.uni-stuttgart.de) *
* . *
* .(Auf Paul, schaff was !) *
* *
* Gunther Nikl Ziegendorfer Chaussee 96 19370 Parchim *
* (gnikl@informatik.uni-rostock.de) *
* *
***************************************************************************/
/***************************************************************************/
/* */
/* includes */
/* */
/***************************************************************************/
#include <exec/types.h>
#ifndef CONST
#define CONST const
#endif
#ifndef INLINE
#define INLINE inline
#endif
#include <dos/dos.h>
#include <dos/rdargs.h>
#include <exec/memory.h>
#include <devices/audio.h>
#include <devices/timer.h>
#include <hardware/cia.h>
#include <graphics/gfxmacros.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <datatypes/pictureclass.h>
#include <libraries/gadtools.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <clib/alib_protos.h>
#include <clib/macros.h>
/*
** structure definitions now!
*/
struct gInfo {
WORD left,top,width,height;
UWORD textnr,kind;
};
struct wInfo {
UWORD idcmp,textnr,gadcnt;
struct gInfo gi[1];
};
struct WinGad {
struct Window *Win;
struct Gadget *Gad;
};
struct BackFillInfo {
STRPTR PictureName;
Object *PictureObject;
struct BitMapHeader *BitMapHeader;
struct BitMap *BitMap;
};
/*
** sizeof(struct Globals) _MUST_ be a multiple of 4!
*/
struct Globals {
/*** library stuff ***/
struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *GadtoolsBase,
*IconBase,
*DataTypesBase;
struct LocaleBase *LocaleBase;
struct Catalog *Catalog;
/*** misc stuff ***/
struct Process *OurTask;
struct WBStartup *WbMsg;
BPTR OldLock;
STRPTR NameBuf;
LONG OldPri;
/*** device stuff ***/
struct MsgPort *WindowPort;
struct MsgPort *TimerPort;
struct timerequest *TimerIO;
struct MsgPort *AudioPort;
struct IOAudio *AudioIO[2];
APTR WaveForm;
/*** graphic stuff ***/
APTR VisualInfo;
struct Menu *Menus;
struct Window *MainWin;
struct RastPort *RPort1;
struct WinGad ColorWin,
AlarmWin;
struct Window *AboutReq;
/*** common variables ***/
LONG Left,
Top,
Width,
Height,
BoLeft,
BoTop,
Width2,
Height2,
ReDrawx1,
ReDrawy1,
ReDrawx2,
ReDrawy2,
xMask,
yMask;
PLANEPTR Buf;
UWORD *PlayTune;
UBYTE *Color;
LONG Std,
Min,
Sec,
AlStd,
AlMin,
St,
Mi,
xOffset,
yOffset;
WORD GadSize;
/*** flags ***/
BYTE TimerOpen,
TimerSent,
AudioOpen,
AudioSent[2],
SoundOn,
xDouble,
yDouble,
ChangedDir,
ChangedPri,
Active,
Alarm,
Filter,
HiRes,
Interlace,
SmartHour,
EndAll;
UBYTE Seconds,
Oval,
Show,
HandType,
HandWidth,
Shadow,
BorderCount,
Chime,
UseImage,
CloseGad,
NoRemap,
RequestNr,
bPad;
/*** structures ***/
struct BackFillInfo BFInfo;
struct WBArg ProgArg;
UBYTE Pens[16],
Must[4];
struct NewWindow NewWindowBuf;
struct Gadget GadgetBuf[4];
struct RastPort RPort2;
struct BitMap BitMap1;
struct TmpRas TempRas;
struct AreaInfo AreaInfo;
UWORD Table[14],
Muster[8][2];
struct NewGadget NewGad;
UWORD wPad;
struct EasyStruct EasyBuf;
};
#define PUB_SCREEN (gb->NewWindowBuf.Screen)
/*
** ptr to the `global' data space (will be on the stack :-)
*/
register struct Globals *gb asm("a4");
/*
** redirect library bases to the `global' data space
*/
#define BASE_NAME gb->LocaleBase
#include <proto/locale.h>
#undef BASE_NAME
#define BASE_NAME gb->DataTypesBase
#include <proto/datatypes.h>
#undef BASE_NAME
#define BASE_NAME gb->IntuitionBase
#include <proto/intuition.h>
#undef BASE_NAME
#define BASE_NAME gb->GadtoolsBase
#include <proto/gadtools.h>
#undef BASE_NAME
#define BASE_NAME gb->GfxBase
#include <proto/graphics.h>
#undef BASE_NAME
#define BASE_NAME gb->IconBase
#include <proto/icon.h>
#undef BASE_NAME
#define BASE_NAME gb->SysBase
#include <proto/exec.h>
#undef BASE_NAME
#define BASE_NAME gb->DOSBase
#include <proto/dos.h>
#undef BASE_NAME
#include <proto/alib.h>
/*
** strcpy() && strlen()
*/
#include <string.h>
/*
** locale string numbers
*/
#include "tolleuhr_locale.h"
/***************************************************************************/
/* */
/* prototypes */
/* */
/***************************************************************************/
LONG OpenMainWindow();
VOID LoadImage();
LONG InitClock();
LONG GetArguments();
VOID MergeToolTypes();
VOID ParseArgs(STRPTR,LONG);
VOID ReadStr(UBYTE *,UBYTE *,UBYTE *,LONG);
LONG XtoD(LONG);
LONG OpenDevs();
LONG OpenLibs();
VOID Main();
VOID CloseLibs();
VOID CloseDevs();
VOID NewSize1();
VOID CloseAboutReq();
VOID CloseGfx();
VOID FreeWindow(struct WinGad *);
VOID CloseWindowSafely(struct Window *);
VOID CheckAboutReq();
VOID CheckWindows();
VOID HandleMenus(ULONG);
LONG NewSize2();
ULONG NextTick();
VOID Rahmen();
VOID ZifferBlatt();
VOID Zeiger(ULONG,LONG,LONG,LONG,LONG);
VOID Zeichnen();
VOID SetPattern();
VOID SaveSettings();
STRPTR SetToolType(STRPTR,STRPTR,LONG,...);
STRPTR GetToolType(LONG);
STRPTR SetStr(STRPTR,STRPTR,LONG);
LONG DtoX(LONG);
VOID TestIfAlarm();
VOID StartTune(CONST UWORD *);
VOID PlayNote();
VOID EndTune();
VOID CreateRequest(struct WinGad *,struct wInfo *,struct TagItem **);
struct Window *OpenWindowShared(struct NewWindow *,CONST struct TagItem *,ULONG);
STRPTR GetCatalogString(LONG);
VOID CopyTiledBitMap(struct BitMap *,LONG,LONG,struct BitMap *,LONG,LONG);
/*
** replacements
*/
Object *new_dt_object(APTR name, ULONG, ...);
ULONG get_dt_attrs(Object *, ULONG, ...);
LONG blt_bitmap(struct BitMap *,LONG,LONG,struct BitMap *,LONG,LONG,LONG,LONG,ULONG,ULONG,PLANEPTR);
/***************************************************************************/
/* */
/* `global' defines */
/* */
/***************************************************************************/
#define GB_GADCOUNT (sizeof(gb->GadgetBuf)/sizeof(struct Gadget))
#define ciaa (*((struct CIA*)0xbfe001L))
/***************************************************************************/
/* */
/* memory clear function (!!! caution: size _MUST_ be a multiple of 4!!!) */
/* */
/***************************************************************************/
STATIC INLINE VOID MEMZEROL(VOID *mem,ULONG size)
{ ULONG *p;
WORD s;
for(p=(ULONG *)mem,s=(size/sizeof(ULONG))-1; s>=0; *p++=NULL,s--);
}
/***************************************************************************/
/* */
/* implementation */
/* */
/***************************************************************************/
LONG TolleUhr()
{ struct Globals globals;
MEMZEROL(&globals,sizeof(struct Globals)); gb = &globals;
gb->SysBase = *(struct ExecBase **)4L;
Main();
return 0;
}
/***************************************************************************/
/* */
/* version string */
/* */
/***************************************************************************/
CONST UBYTE Version[] = "$VER: TolleUhr "VERSION" by M.Fleischer and G.Nikl in 1993/95";
#define PROGNAME ((UBYTE *)(&Version[6]))
/***************************************************************************/
/* */
/* open clock window */
/* */
/***************************************************************************/
#define MAINIDCMP (IDCMP_NEWSIZE | IDCMP_REFRESHWINDOW | IDCMP_MENUPICK | \
IDCMP_CLOSEWINDOW | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW)
CONST struct TagItem WindowTags[] = {
{ WA_InnerWidth , 148 },
{ WA_InnerHeight, 72 },
{ WA_AutoAdjust ,TRUE },
{ TAG_DONE ,NULL }
};
LONG OpenMainWindow()
{
struct NewWindow *nw;
struct Window *win;
LONG ret;
nw = &gb->NewWindowBuf;
nw->LeftEdge = gb->Left;
nw->TopEdge = gb->Top;
nw->Width = gb->Width;
nw->Height = gb->Height;
nw->BlockPen = 1;
nw->Flags = WFLG_SIMPLE_REFRESH | WFLG_BORDERLESS | WFLG_NEWLOOKMENUS;
nw->FirstGadget = &gb->GadgetBuf[0];
nw->MinWidth = 10;
nw->MinHeight = 10;
nw->MaxWidth = 65535;
nw->MaxHeight = 65535;
nw->Type = PUBLICSCREEN;
ret = 0;
if ((gb->MainWin=(win=OpenWindowShared(nw,&WindowTags[2],MAINIDCMP))) != NULL)
{
gb->RPort1 = win->RPort;
SetWindowTitles(win,(UBYTE *)-1L,PROGNAME);
SetMenuStrip(win,gb->Menus);
if (!gb->BFInfo.BitMap || gb->UseImage)
OffMenu(win,(gb->UseImage ? FULLMENUNUM(3,NOITEM,NOSUB) : FULLMENUNUM(1,8,NOSUB)));
SetAPen(gb->RPort1,gb->Pens[0]);
if (!NewSize2())
{
NextTick();
Rahmen();
ZifferBlatt();
Zeichnen();
ret = 1;
}
}
return ret;
}
/***************************************************************************/
/* */
/* load background image via datatypes */
/* */
/***************************************************************************/
CONST struct TagItem PicTags[] = {
{ DTA_GroupID ,GID_PICTURE },
{ PDTA_FreeSourceBitMap,TRUE },
{ OBP_Precision ,PRECISION_IMAGE },
{ TAG_DONE ,NULL }
};
VOID LoadImage()
{ STRPTR name;
Object *obj;
if (gb->DataTypesBase)
if ((name=gb->BFInfo.PictureName) != NULL)
{
gb->BFInfo.PictureObject = obj =
new_dt_object(name,
PDTA_Screen,PUB_SCREEN,
PDTA_Remap ,(gb->NoRemap ? FALSE : TRUE),
TAG_MORE ,PicTags);
if (obj != NULL)
if (DoMethod(obj,DTM_PROCLAYOUT,NULL,1))
get_dt_attrs(obj,
PDTA_BitMapHeader,&gb->BFInfo.BitMapHeader,
PDTA_DestBitMap ,&gb->BFInfo.BitMap,
TAG_DONE);
}
}
/***************************************************************************/
/* */
/* initialize all graphics */
/* */
/***************************************************************************/
CONST UBYTE gadgetInfo[] = {
GADGHNONE ,GTYP_CLOSE,
GADGHNONE|GRELRIGHT ,GTYP_WDEPTH,
GADGHNONE|GRELRIGHT|GRELBOTTOM,GTYP_SIZING,
GADGHNONE|GRELWIDTH|GRELHEIGHT,GTYP_WDRAGGING
};
enum {
MENU_PROJECT=0,
MENU_PROJECT_ABOUT,
MENU_PROJECT_QUIT,
MENU_SETTINGS,
MENU_SETTINGS_SECONDS,
MENU_SETTINGS_OVAL,
MENU_SETTINGS_SHOW,
MENU_SETTINGS_SHOW_MINUTES,
MENU_SETTINGS_SHOW_HOURS,
MENU_SETTINGS_SHOW_QUARTER,
MENU_SETTINGS_SHOW_ONE,
MENU_SETTINGS_SHOW_NONE,
MENU_SETTINGS_HANDS,
MENU_SETTINGS_HANDS_LINE,
MENU_SETTINGS_HANDS_TRIANGLE,
MENU_SETTINGS_HANDS_RHOMBUS,
MENU_SETTINGS_HANDS_RECTANGLE,
MENU_SETTINGS_HANDS_BARLABEL,
MENU_SETTINGS_HANDS_VERYTHIN,
MENU_SETTINGS_HANDS_THIN,
MENU_SETTINGS_HANDS_NORMAL,
MENU_SETTINGS_HANDS_THICK,
MENU_SETTINGS_HANDS_VERYTHICK,
MENU_SETTINGS_SHADOW,
MENU_SETTINGS_BORDER,
MENU_SETTINGS_BORDER_NONE,
MENU_SETTINGS_BORDER_SINGLE,
MENU_SETTINGS_BORDER_DOUBLE,
MENU_SETTINGS_BORDER_BARLABEL,
MENU_SETTINGS_BORDER_HIRES,
MENU_SETTINGS_BORDER_INTERLACE,
MENU_SETTINGS_CHIME,
MENU_SETTINGS_CHIME_NONE,
MENU_SETTINGS_CHIME_HOURS,
MENU_SETTINGS_CHIME_QUARTER,
MENU_SETTINGS_CHIME_BARLABEL,
MENU_SETTINGS_CHIME_SMART,
MENU_SETTINGS_ALARM,
MENU_SETTINGS_ALARM_SET,
MENU_SETTINGS_ALARM_ON,
MENU_SETTINGS_USEIMAGE,
MENU_SETTINGS_CLOSEGAD,
MENU_SETTINGS_BARLABEL,
MENU_SETTINGS_SAVE,
MENU_COLORS,
MENU_COLORS_SECONDS,
MENU_COLORS_MINAPEN,
MENU_COLORS_MINOPEN,
MENU_COLORS_HOURAPEN,
MENU_COLORS_HOUROPEN,
MENU_COLORS_SHADOW,
MENU_COLORS_STR12,
MENU_COLORS_QUARTER,
MENU_COLORS_HOURS,
MENU_COLORS_MINUTES,
MENU_COLORS_BORDER0,
MENU_COLORS_BORDER1,
MENU_COLORS_BORDER2,
MENU_COLORS_BORDER3,
MENU_PATTERN,
MENU_PATTERN_COLOR0,
MENU_PATTERN_COLOR1,
MENU_PATTERN_COLOR2,
MENU_PATTERN_COLOR3
};
CONST UBYTE MenuInfo[] = {
NM_TITLE,MSG_PROJECT,0,0,
NM_ITEM,MSG_ABOUT,0,0,
NM_ITEM,MSG_QUIT,0,0,
NM_TITLE,MSG_SETTINGS,0,0,
NM_ITEM,MSG_SECONDS,CHECKIT|MENUTOGGLE,0,
NM_ITEM,MSG_OVAL,CHECKIT|MENUTOGGLE,0,
NM_ITEM,MSG_SHOW,0,0,
NM_SUB,MSG_MINUTES,CHECKIT,2|4|8|16,
NM_SUB,MSG_HOURS,CHECKIT,1|4|8|16,
NM_SUB,MSG_QUARTER,CHECKIT,1|2|8|16,
NM_SUB,MSG_ONE,CHECKIT,1|2|4|16,
NM_SUB,MSG_NONE,CHECKIT,1|2|4|8,
NM_ITEM,MSG_HANDS,0,0,
NM_SUB,MSG_LINE,CHECKIT,2|4|8,
NM_SUB,MSG_TRIANGLE,CHECKIT,1|4|8,
NM_SUB,MSG_RHOMBUS,CHECKIT,1|2|8,
NM_SUB,MSG_RECTANGLE,CHECKIT,1|2|4,
NM_SUB,(UBYTE)NM_BARLABEL,0,0,
NM_SUB,MSG_VERYTHIN,CHECKIT,128+(2|4|8|16),
NM_SUB,MSG_THIN,CHECKIT,128+(1|4|8|16),
NM_SUB,MSG_NORMAL,CHECKIT,128+(1|2|8|16),
NM_SUB,MSG_THICK,CHECKIT,128+(1|2|4|16),
NM_SUB,MSG_VERYTHICK,CHECKIT,128+(1|2|4|8),
NM_ITEM,MSG_SHADOW,CHECKIT|MENUTOGGLE,0,
NM_ITEM,MSG_BORDER,0,0,
NM_SUB,MSG_NONE,CHECKIT,2|4,
NM_SUB,MSG_SINGLE,CHECKIT,1|4,
NM_SUB,MSG_DOUBLE,CHECKIT,1|2,
NM_SUB,(UBYTE)NM_BARLABEL,0,0,
NM_SUB,MSG_HIRES,CHECKIT|MENUTOGGLE,0,
NM_SUB,MSG_INTERLACE,CHECKIT|MENUTOGGLE,0,
NM_ITEM,MSG_CHIME,0,0,
NM_SUB,MSG_NONE,CHECKIT,2|4,
NM_SUB,MSG_HOURS,CHECKIT,1|4,
NM_SUB,MSG_QUARTER,CHECKIT,1|2,
NM_SUB,(UBYTE)NM_BARLABEL,0,0,
NM_SUB,MSG_SMART,CHECKIT|MENUTOGGLE,0,
NM_ITEM,MSG_ALARM,0,0,
NM_SUB,MSG_SET,0,0,
NM_SUB,MSG_ON,CHECKIT|MENUTOGGLE,0,
NM_ITEM,MSG_USEIMAGE,CHECKIT|MENUTOGGLE,0,
NM_ITEM,MSG_CLOSEGAD,CHECKIT|MENUTOGGLE,0,
NM_ITEM,(UBYTE)NM_BARLABEL,0,0,
NM_ITEM,MSG_SAVESETTINGS,0,0,
NM_TITLE,MSG_COLORS,0,0,
NM_ITEM,MSG_SECONDS,0,0,
NM_ITEM,MSG_MINAPEN,0,0,
NM_ITEM,MSG_MINOPEN,0,0,
NM_ITEM,MSG_HOURAPEN,0,0,
NM_ITEM,MSG_HOUROPEN,0,0,
NM_ITEM,MSG_SHADOW,0,0,
NM_ITEM,MSG_STR12,0,0,
NM_ITEM,MSG_QUARTER,0,0,
NM_ITEM,MSG_HOURS,0,0,
NM_ITEM,MSG_MINUTES,0,0,
NM_ITEM,MSG_BORDER0,0,0,
NM_ITEM,MSG_BORDER1,0,0,
NM_ITEM,MSG_BORDER2,0,0,
NM_ITEM,MSG_BORDER3,0,0,
NM_TITLE,MSG_PATTERN,0,0,
NM_ITEM,MSG_COLOR0,0,0,
NM_ITEM,MSG_COLOR1,0,0,
NM_ITEM,MSG_COLOR2,0,0,
NM_ITEM,MSG_COLOR3,0,0
};
#define NM_ITEMCOUNT (sizeof(MenuInfo)/(4*sizeof(UBYTE)))
CONST struct TagItem MenuTags[] = {
{ GTMN_NewLookMenus,TRUE },
{ TAG_DONE ,NULL }
};
LONG InitClock()
{ struct NewMenu menubuf[NM_ITEMCOUNT+1],*nm;
struct Gadget *gad;
CONST UBYTE *p;
LONG tmp,index,ret;
WORD i,num;
LoadImage();
SetPattern();
for(gad=&gb->GadgetBuf[0],p=&gadgetInfo[0],num=1,i=GB_GADCOUNT-1; i>=0; i--)
{ gad->Width = num;
gad->Height = num;
gad->Flags = *p++;
gad->Activation = num; /* GACT_RELVERIFY */
gad->GadgetType = *p++;
gad++;
gad[-1].NextGadget = gad;
}
gad[-1].NextGadget = NULL;
MEMZEROL(&menubuf[0],sizeof(menubuf));
for(nm=&menubuf[0],p=&MenuInfo[0],i=NM_ITEMCOUNT-1; i>=0; i--)
{ nm->nm_Type = *p++;
if ((tmp=(BYTE)*p++) >= 0) tmp=(LONG)GetCatalogString(tmp);
nm->nm_Label = (STRPTR)tmp;
nm->nm_Flags = (UWORD)*p++;
if ((num=(BYTE)*p++) < 0) num=(((num&0x7f))<<5);
nm->nm_MutualExclude = (ULONG)num;
nm++;
}
menubuf[MENU_PROJECT_ABOUT].nm_CommKey = GetCatalogString(MSG_ABOUTKEY);
menubuf[MENU_PROJECT_QUIT].nm_CommKey = GetCatalogString(MSG_QUITKEY);
menubuf[MENU_SETTINGS_SAVE].nm_CommKey = GetCatalogString(MSG_SAVEKEY);
ret = 0;
if ((gb->VisualInfo=GetVisualInfoA(PUB_SCREEN,NULL)) != NULL)
{
nm = &menubuf[0]; i = CHECKED;
nm[MENU_SETTINGS_SECONDS].nm_Flags
|= i & (gb->Seconds ? -1 : 0);
nm[MENU_SETTINGS_OVAL].nm_Flags
|= i & (gb->Oval ? -1 : 0);
index = MENU_SETTINGS_SHOW+gb->Show+1;
nm[index].nm_Flags
|= i;
index = MENU_SETTINGS_HANDS+gb->HandType+1;
nm[index].nm_Flags
|= i;
index = MENU_SETTINGS_HANDS+gb->HandWidth+6;
nm[index].nm_Flags
|= i;
nm[MENU_SETTINGS_SHADOW].nm_Flags
|= i & (gb->Shadow ? -1 : 0);
index = MENU_SETTINGS_BORDER+gb->BorderCount+1;
nm[index].nm_Flags
|= i;
nm[MENU_SETTINGS_BORDER_HIRES].nm_Flags
|= i & (gb->HiRes ? -1 : 0);
nm[MENU_SETTINGS_BORDER_INTERLACE].nm_Flags
|= i & (gb->Interlace ? -1 : 0);
index = MENU_SETTINGS_CHIME+gb->Chime+1;
nm[index].nm_Flags
|= i;
nm[MENU_SETTINGS_CHIME_SMART].nm_Flags
|= i & (gb->SmartHour ? -1 : 0);
nm[MENU_SETTINGS_USEIMAGE].nm_Flags
|= i & (gb->BFInfo.PictureObject && gb->UseImage ? -1 : 0);
nm[MENU_SETTINGS_CLOSEGAD].nm_Flags
|= i & (gb->CloseGad ? -1 : 0);
if ((gb->Menus=CreateMenusA(&menubuf[0],NULL)) != NULL)
if (LayoutMenusA(gb->Menus,gb->VisualInfo,(struct TagItem *)MenuTags))
ret = OpenMainWindow();
}
return ret;
}
/***************************************************************************/
/* */
/* get argumets either from CLI or WB */
/* */
/***************************************************************************/
LONG GetArguments()
{ struct WBStartup *wm;
struct WBArg *arg;
STRPTR buf;
if ((wm=gb->WbMsg) != NULL)
{
arg = wm->sm_ArgList;
if (wm->sm_NumArgs>1)
arg++;
gb->ProgArg.wa_Lock = arg->wa_Lock;
gb->ProgArg.wa_Name = arg->wa_Name;
gb->OldLock = CurrentDir(arg->wa_Lock);
gb->ChangedDir = -1;
MergeToolTypes();
}
else
if ((gb->NameBuf=(buf=AllocVec(124,MEMF_ANY))) != NULL)
{
gb->ProgArg.wa_Lock = GetProgramDir();
GetProgramName(buf,124);
gb->ProgArg.wa_Name = FilePart(buf);
ParseArgs(NULL,0);
}
if (PUB_SCREEN == NULL)
return 0;
return 1;
}
/*
** read all tooltypes
*/
STATIC INLINE STRPTR stpcpy(STRPTR dst,STRPTR src)
{
while((*dst++=*src++)); return(dst-1);
}
VOID MergeToolTypes()
{ struct DiskObject *dobj;
STRPTR argstr,string,p;
LONG arglen,strln;
BPTR old_cd;
char **tt;
argstr = (STRPTR)&gb->EasyBuf; *argstr = '\n'; arglen = 1; string=NULL;
old_cd = CurrentDir(gb->ProgArg.wa_Lock);
if ((dobj=GetDiskObject(gb->ProgArg.wa_Name)) != NULL)
{
tt = dobj->do_ToolTypes; strln = 1;
while (*tt != NULL)
{
strln+=strlen(*tt++)+1;
}
if ((string=AllocVec((strln+sizeof(ULONG)-1)&~(sizeof(ULONG)-1),MEMF_ANY)) != NULL)
{
tt = dobj->do_ToolTypes; p=string;
while (*tt != NULL)
{
p=stpcpy(p,*tt++); *p++ = ' ';
}
*p = '\n';
argstr = string; arglen = strln;
}
FreeDiskObject(dobj);
}
ParseArgs(argstr,arglen);
if (string)
FreeVec(string);
(VOID)CurrentDir(old_cd);
}
/*
** parse arguments and set default values
*/
enum {OPT_NULL=-1,OPT_TOP,OPT_LEFT,OPT_WIDTH,OPT_HEIGHT,OPT_SECONDS,
OPT_PATTERN,OPT_OVAL,OPT_SHADOW,OPT_SHOWFACE,OPT_HANDTYPE,
OPT_HANDWIDTH,OPT_DRAWPENS,OPT_BORDERTYPE,OPT_CHIME,OPT_CLOSEGAD,
OPT_USEIMAGE,OPT_NOREMAP,OPT_IMAGE,OPT_PUBSCREEN,OPT_TASKPRI,
OPT_SIZEOF};
#define TEMPLATE "/M,TOP/N,LEFT/N,WIDTH/N,HEIGHT/N,SECONDS/S,PATTERN/K,OVAL/S," \
"SHADOW/S,SHOWFACE/N,HANDTYPE/N,HANDWIDTH/N,DRAWPENS/K," \
"BORDERTYPE/N,CHIME/N,CLOSEGAD/S,USEIMAGE/S,NOREMAP/S," \
"IMAGE/K,PUBSCREEN/K,TASKPRI/N"
CONST UBYTE Pens[] = {
2,0,2,0,2,1,2,2,2,2,0,1,2,3
};
VOID ParseArgs(STRPTR argstr,LONG length)
{ struct RDArgs *rda,*args;
struct Screen *scr;
LONG result[OPT_SIZEOF+1],*res,def,tmp;
STRPTR tmpl;
MEMZEROL(&result[0],sizeof(result));
if ((rda=AllocDosObject(DOS_RDARGS,NULL)) != NULL)
{
rda->RDA_Source.CS_Buffer = argstr;
rda->RDA_Source.CS_Length = length;
tmpl = TEMPLATE; res = &result[0];
if (rda->RDA_Source.CS_Buffer == NULL)
{
res++; tmpl+=3;
}
args=ReadArgs(tmpl,res,rda);
}
res = &result[1];
def = 50;
if (res[OPT_TOP])
{
tmp = *(LONG *)res[OPT_TOP]; if (tmp >= 0) def = tmp;
}
gb->Top = def;
def = 50;
if (res[OPT_LEFT])
{
tmp = *(LONG *)res[OPT_LEFT]; if (tmp >= 0) def = tmp;
}
gb->Left = def;
def = 108;
if (res[OPT_WIDTH])
{
tmp = *(LONG *)res[OPT_WIDTH]; if (tmp >= 10) def = tmp;
}
gb->Width = def;
def = 54;
if (res[OPT_HEIGHT])
{
tmp = *(LONG *)res[OPT_HEIGHT]; if (tmp >= 10) def = tmp;
}
gb->Height = def;
gb->Seconds = res[OPT_SECONDS];
ReadStr(&gb->Must[0],(STRPTR)res[OPT_PATTERN],&gb->Must[0],4);
gb->Oval = res[OPT_OVAL];
gb->Shadow = res[OPT_SHADOW];
def = 1;
if (res[OPT_SHOWFACE])
{
tmp = *(LONG *)res[OPT_SHOWFACE]; if ((ULONG)tmp < 5) def = tmp;
}
gb->Show = def;
def = 2;
if (res[OPT_HANDTYPE])
{
tmp = *(LONG *)res[OPT_HANDTYPE]; if ((ULONG)tmp < 4) def = tmp;
}
gb->HandType = def;
def = 2;
if (res[OPT_HANDWIDTH])
{
tmp = *(LONG *)res[OPT_HANDWIDTH]; if ((ULONG)tmp < 5) def = tmp;
}
gb->HandWidth = def;
ReadStr(&gb->Pens[0],(STRPTR)res[OPT_DRAWPENS],(STRPTR)&Pens[0],14);
def = 6;
if (res[OPT_BORDERTYPE])
{
tmp = *(LONG *)res[OPT_BORDERTYPE]; if ((ULONG)tmp <= 2+4+8) def = tmp;
}
if (def & 4)
{
gb->HiRes = -1; def -= 4;
}
if (def & 8)
{
gb->Interlace = -1; def -= 8;
}
gb->BorderCount = def;
def = 0;
if (res[OPT_CHIME])
{
tmp = *(LONG *)res[OPT_CHIME]; if ((ULONG)tmp <= 2+4) def = tmp;
}
if (def & 4)
{
gb->SmartHour = -1; def -= 4;
}
gb->Chime = def;
gb->CloseGad = res[OPT_CLOSEGAD];
gb->UseImage = res[OPT_USEIMAGE];
gb->NoRemap = res[OPT_NOREMAP];
if (res[OPT_IMAGE])
if ((gb->BFInfo.PictureName=AllocVec(1+strlen((STRPTR)res[OPT_IMAGE]),MEMF_ANY)) != NULL)
strcpy(gb->BFInfo.PictureName,(STRPTR)res[OPT_IMAGE]);
if ((scr=(struct Screen *)res[OPT_PUBSCREEN]) != NULL)
{ if ((scr=LockPubScreen((STRPTR)scr)) == NULL)
scr = LockPubScreen((STRPTR)scr); }
else
scr = LockPubScreen((STRPTR)scr);
PUB_SCREEN = scr;
if (res[OPT_TASKPRI])
{
tmp = *(LONG *)res[OPT_TASKPRI]; if (tmp > 5) tmp = 5;
gb->OldPri = SetTaskPri((struct Task *)gb->OurTask,tmp);
gb->ChangedPri = -1;
}
if (args != NULL)
FreeArgs(args);
if (rda != NULL)
FreeDosObject(DOS_RDARGS,rda);
}
/*
** init pen-buffer with `def' and replace with src (if non zero)
*/
VOID ReadStr(UBYTE *dst,UBYTE *src,UBYTE *def,LONG cnt)
{
CopyMem(def,dst,cnt);
if (src != NULL)
if (*src=='x' || *src=='X') /* hex */
do
{ if (!*src++ || !*src++)
return;
*dst++ = (XtoD(src[-1])<<4) + XtoD(*src);
} while (--cnt);
else
do /* decimal */
{ if (!*src)
return;
*dst++ = XtoD(*src++);
} while (--cnt);
}
LONG XtoD(LONG a)
{
if (a>='0' && a<='9')
return (a-'0');
if (a>='a' && a<='f')
return (a-'a'+10);
if (a>='A' && a<='F')
return (a-'A'+10);
return 0;
}
/***************************************************************************/
/* */
/* open all devices */
/* */
/***************************************************************************/
LONG OpenDevs()
{ LONG ret = 0;
if ((gb->WindowPort=CreateMsgPort()) != NULL)
if ((gb->TimerPort=CreateMsgPort()) != NULL)
if ((gb->TimerIO=CreateIORequest(gb->TimerPort,sizeof(struct timerequest))) != NULL)
if (!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)gb->TimerIO,0))
{
gb->TimerOpen = -1;
if ((gb->AudioPort=CreateMsgPort()) != NULL)
if ((gb->AudioIO[0]=CreateIORequest(gb->AudioPort,sizeof(struct IOAudio))) != NULL)
if ((gb->AudioIO[1]=CreateIORequest(gb->AudioPort,sizeof(struct IOAudio))) != NULL)
if (!OpenDevice(AUDIONAME,0,(struct IORequest *)gb->AudioIO[0],0))
{
gb->AudioOpen = -1;
if ((gb->WaveForm=AllocMem(8,MEMF_CHIP|MEMF_PUBLIC|MEMF_CLEAR)) != NULL)
{
((ULONG *)gb->WaveForm)[0]=0x7f807f80; /* rectangle */
ret = 1;
}
}
}
return ret;
}
/***************************************************************************/
/* */
/* open all libraries */
/* */
/***************************************************************************/
LONG OpenLibs()
{ LONG ret = 0;
if ((gb->DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37L)) != NULL)
if ((gb->IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L)) != NULL)
if ((gb->GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L)) != NULL)
if ((gb->GadtoolsBase=OpenLibrary("gadtools.library",37L)) != NULL)
if ((gb->IconBase=OpenLibrary("icon.library",37L)) != NULL)
{
gb->DataTypesBase = OpenLibrary("datatypes.library",39L);
if ((gb->LocaleBase=(struct LocaleBase *)OpenLibrary("locale.library",38L)) != NULL)
{
gb->Catalog = OpenCatalogA(NULL,"tolleuhr.catalog",NULL);
}
ret = 1;
}
return ret;
}
/***************************************************************************/
/* */
/* main function */
/* */
/***************************************************************************/
VOID Main()
{ struct Process *proc;
STRPTR buf;
ULONG mask;
gb->OurTask = proc = (struct Process *)FindTask(NULL);
if (!proc->pr_CLI)
{
WaitPort(&proc->pr_MsgPort);
gb->WbMsg = (struct WBStartup *)GetMsg(&proc->pr_MsgPort);
}
if (OpenLibs())
{
if (OpenDevs())
{
if (GetArguments())
{
if (InitClock())
{
for(;;)
{
mask = 1L<<SIGBREAKB_CTRL_C | 1L<<gb->WindowPort->mp_SigBit |
1L<<gb->TimerPort->mp_SigBit | 1L<<gb->AudioPort->mp_SigBit;
if (gb->AboutReq)
mask |= 1L<<gb->AboutReq->UserPort->mp_SigBit;
if (Wait(mask) & SIGBREAKF_CTRL_C) /* User-Break */
break;
if (GetMsg(gb->TimerPort))
{
if (NextTick())
{
ZifferBlatt(); TestIfAlarm();
}
Zeichnen();
}
if (GetMsg(gb->AudioPort))
PlayNote();
CheckAboutReq();
CheckWindows();
if (gb->EndAll)
break;
}
}
CloseGfx();
if (gb->ChangedPri)
(VOID)SetTaskPri((struct Task *)gb->OurTask,gb->OldPri);
if ((buf=gb->NameBuf) != NULL)
FreeVec(buf);
if (gb->ChangedDir)
(VOID)CurrentDir(gb->OldLock);
}
}
CloseDevs();
}
CloseLibs();
if (gb->WbMsg)
{
Forbid();
ReplyMsg((struct Message *)gb->WbMsg);
}
}
/***************************************************************************/
/* */
/* close all libraries */
/* */
/***************************************************************************/
VOID CloseLibs()
{ struct Library *lib;
if (gb->LocaleBase != NULL)
{
CloseCatalog(gb->Catalog); CloseLibrary((struct Library *)gb->LocaleBase);
}
if ((lib=gb->DataTypesBase) != NULL)
CloseLibrary(lib);
if ((lib=gb->IconBase) != NULL)
CloseLibrary(lib);
if ((lib=gb->GadtoolsBase) != NULL)
CloseLibrary(lib);
if ((lib=(struct Library *)gb->GfxBase) != NULL)
CloseLibrary(lib);
if ((lib=(struct Library *)gb->IntuitionBase) != NULL)
CloseLibrary(lib);
if ((lib=(struct Library *)gb->DOSBase) != NULL)
CloseLibrary(lib);
}
/***************************************************************************/
/* */
/* close all devices */
/* */
/***************************************************************************/
VOID StopIO(struct IORequest *ioReq)
{
AbortIO(ioReq); WaitIO(ioReq);
}
VOID CloseDevs()
{ struct IORequest *ioreq,*io;
struct MsgPort *port;
APTR buf;
if (gb->AudioOpen)
{
if (gb->AudioSent[1])
StopIO((struct IORequest *)gb->AudioIO[1]);
io = (struct IORequest *)gb->AudioIO[0];
if (gb->AudioSent[0])
StopIO(io);
if (gb->SoundOn)
EndTune();
CloseDevice(io);
}
if ((ioreq=(struct IORequest *)gb->AudioIO[1]) != NULL)
DeleteIORequest(ioreq);
if ((ioreq=(struct IORequest *)gb->AudioIO[0]) != NULL)
DeleteIORequest(ioreq);
if ((port=gb->AudioPort) != NULL)
DeleteMsgPort(port);
if ((buf=gb->WaveForm) != NULL)
FreeMem(buf,8);
if (gb->TimerOpen)
{
io = (struct IORequest *)gb->TimerIO;
if (gb->TimerSent)
StopIO(io);
CloseDevice(io);
}
if ((ioreq=(struct IORequest *)gb->TimerIO) != NULL)
DeleteIORequest(ioreq);
if ((port=gb->TimerPort) != NULL)
DeleteMsgPort(port);
if ((port=gb->WindowPort) != NULL)
DeleteMsgPort(port);
}
/***************************************************************************/
/* */
/* close graphic stuff */
/* */
/***************************************************************************/
VOID NewSize1()
{ PLANEPTR buf,*p;
LONG i;
if ((buf=gb->Buf) != NULL)
FreeRaster(buf,gb->Width2,gb->Height2);
p=&gb->BitMap1.Planes[0];
if ((i=gb->BitMap1.Depth) > 0)
do
{ if ((buf=*p) != NULL)
FreeRaster(buf,gb->Width2,gb->Height2);
*p++=NULL;
} while(--i);
}
/*
** discard `About'
*/
VOID CloseAboutReq()
{ struct Window *req;
if ((req=gb->AboutReq) != NULL)
{
FreeSysRequest(req); gb->AboutReq = NULL;
}
}
/*
** discard all windows and other gfx stuff
*/
VOID CloseGfx()
{ struct Screen *scr;
struct Menu *menus;
Object *img;
APTR vi;
NewSize1();
CloseAboutReq();
FreeWindow(&gb->AlarmWin);
FreeWindow(&gb->ColorWin);
CloseWindowSafely(gb->MainWin);
if ((menus=gb->Menus) != NULL)
FreeMenus(menus);
if ((vi=gb->VisualInfo) != NULL)
FreeVisualInfo(vi);
if ((img=gb->BFInfo.PictureObject) != NULL)
DisposeDTObject(img);
if ((scr=PUB_SCREEN) != NULL)
UnlockPubScreen(NULL,scr);
}
/*
** close a tool window
*/
VOID FreeWindow(struct WinGad *wg)
{ struct Window *win;
if ((win=wg->Win) != NULL)
{
CloseWindowSafely(win);
wg->Win = NULL;
FreeGadgets(wg->Gad);
wg->Gad = NULL;
}
}
/*
** close window with shared IDCMP
*/
VOID CloseWindowSafely(struct Window *win)
{ struct Node *msg,*succ;
Forbid();
msg=win->UserPort->mp_MsgList.lh_Head; /* assumes valid port */
while ((succ=msg->ln_Succ)!=NULL)
{ if (((struct IntuiMessage *)msg)->IDCMPWindow==win)
{
Remove(msg); ReplyMsg((struct Message *)msg);
}
msg=succ;
}
win->UserPort=NULL;
ModifyIDCMP(win,0L);
Permit();
ClearMenuStrip(win);
CloseWindow(win);
}
/***************************************************************************/
/* */
/* process all input events */
/* */
/***************************************************************************/
VOID CheckAboutReq()
{ struct Window *req;
if ((req=gb->AboutReq) != NULL)
if (SysReqHandler(req,NULL,FALSE) != -2)
CloseAboutReq();
}
/*
** process all windows with shared IDCMP
*/
VOID CheckWindows()
{ struct IntuiMessage *imsg;
struct Window *iwin;
ULONG class,code;
APTR iadr;
LONG tmp;
while ((imsg=GT_GetIMsg(gb->WindowPort)) != NULL)
{ class = imsg->Class;
code = imsg->Code;
iadr = imsg->IAddress;
iwin = imsg->IDCMPWindow;
GT_ReplyIMsg(imsg);
if (gb->MainWin == iwin)
{ switch (class)
{ case NEWSIZE:
NewSize1();
if ((gb->EndAll=NewSize2()))
return;
Rahmen();
ZifferBlatt();
Zeichnen();
break;
case REFRESHWINDOW:
gb->ReDrawx1=(tmp=gb->BoLeft);
gb->ReDrawx2=tmp+gb->Width2-1;
gb->ReDrawy1=(tmp=gb->BoTop);
gb->ReDrawy2=tmp+gb->Height2-1;
BeginRefresh(gb->MainWin);
Rahmen();
Zeichnen();
EndRefresh(gb->MainWin,TRUE);
break;
case MENUPICK:
HandleMenus(code);
if (gb->EndAll)
return;
break;
case CLOSEWINDOW:
if ((gb->EndAll=gb->CloseGad))
return;
break;
case ACTIVEWINDOW:
gb->Active = -1;
Rahmen();
break;
case INACTIVEWINDOW:
gb->Active = 0;
Rahmen();
break;
}
}
else
if (gb->ColorWin.Win == iwin)
{ if (class == CLOSEWINDOW || class == GADGETUP)
{ if (class!=CLOSEWINDOW) /* kann nur das Palette-Gadget sein */
{ *gb->Color = code;
SetPattern();
Rahmen();
ZifferBlatt();
Zeichnen();
}
FreeWindow(&gb->ColorWin);
}
}
else
if (gb->AlarmWin.Win == iwin)
{ if (class==CLOSEWINDOW || class==MOUSEMOVE || class==GADGETUP)
{ if (class!=CLOSEWINDOW)
{ switch(((struct Gadget *)iadr)->GadgetID)
{ case 1:
gb->St = code;
goto endit;
case 2:
gb->Mi = code;
goto endit;
case 3:
gb->AlStd = gb->St; gb->AlMin = gb->Mi; gb->Alarm = -1;
case 4:
break;
}
}
FreeWindow(&gb->AlarmWin);
if (gb->Alarm)
{ struct MenuItem *item=ItemAddress(gb->Menus,FULLMENUNUM(1,7,1));
if (!(item->Flags&CHECKED))
{ ClearMenuStrip(gb->MainWin);
item->Flags |= CHECKED;
ResetMenuStrip(gb->MainWin,gb->Menus);
}
}
endit: ;
}
}
}
}
/*
** function for Menu-Handling
*/
CONST UWORD ColorWinInfo[] = {
CLOSEWINDOW | PALETTEIDCMP, MSG_CHOOSE,
1,
4,2,144,68,0,PALETTE_KIND,
};
CONST UWORD AlarmWinInfo[] = {
CLOSEWINDOW | BUTTONIDCMP | SLIDERIDCMP, MSG_ALARM,
4,
42,15,20,39,0 ,SLIDER_KIND,
82,15,20,39,0 ,SLIDER_KIND,
2,58,70,12,MSG_USE ,BUTTON_KIND,
76,58,70,12,MSG_CANCEL,BUTTON_KIND,
};
CONST struct TagItem AlarmGadTags1[] = {
{ GTSL_Min ,1 },
{ GTSL_Max ,12 },
{ GTSL_MaxLevelLen,10 },
{ GTSL_LevelPlace ,PLACETEXT_ABOVE },
{ PGA_FREEDOM ,LORIENT_VERT },
{ GA_RelVerify ,TRUE },
{ TAG_DONE ,NULL }
};
CONST struct TagItem AlarmGadTags2[] = {
{ GTSL_Min ,0 },
{ GTSL_Max ,59 },
{ GTSL_MaxLevelLen,5 },
{ GTSL_LevelPlace ,PLACETEXT_ABOVE },
{ PGA_FREEDOM ,LORIENT_VERT },
{ GA_RelVerify ,TRUE },
{ TAG_DONE ,NULL }
};
VOID HandleMenus(ULONG code)
{ struct TagItem tags[6],*tt[4];
struct MenuItem *item;
struct Window *req;
ULONG mnum,inum,snum,*p;
BYTE check;
while ((UWORD)code != MENUNULL)
{
item = ItemAddress(gb->Menus,code);
mnum = MENUNUM(code); inum = ITEMNUM(code); snum = SUBNUM(code);
(UWORD)code = item->NextSelect;
switch (mnum)
{
case 0: /* Project */
switch (inum)
{
case 0: /* About */
if (gb->AboutReq == NULL)
{
gb->EasyBuf.es_StructSize = 5*sizeof(ULONG);
gb->EasyBuf.es_Flags = 0;
gb->EasyBuf.es_Title = GetCatalogString(MSG_ABOUT);
gb->EasyBuf.es_TextFormat = PROGNAME;
gb->EasyBuf.es_GadgetFormat = GetCatalogString(MSG_DESCRIPTION);
req = BuildEasyRequestArgs(gb->MainWin,&gb->EasyBuf,NULL,NULL);
if ((ULONG)req>1)
gb->AboutReq = req;
}
break;
case 1: /* Quit */
gb->EndAll = -1; return;
break;
}
break;
case 1: /* Settings */
check = (item->Flags&CHECKED ? 1 : 0);
switch (inum)
{
case 0: /* Seconds */
gb->Seconds = check;
if (gb->TimerSent)
{
AbortIO((struct IORequest *)gb->TimerIO);
WaitIO((struct IORequest *)gb->TimerIO);
gb->TimerSent = 0;
}
NextTick();
break;
case 1: /* Oval */
gb->Oval = check;
break;
case 2: /* Show */
if (check)
gb->Show = snum;
break;
case 3: /* Hands */
if (check)
switch (snum)
{ case 0: case 1: case 2: case 3:
gb->HandType = snum;
break;
case 5: case 6: case 7: case 8: case 9:
gb->HandWidth = snum-5;
break;
}
break;
case 4: /* Shadow */
gb->Shadow = check;
break;
case 5: /* Border */
switch (snum)
{ case 0: case 1: case 2:
if (check)
gb->BorderCount = snum;
break;
case 4:
gb->HiRes = check;
break;
case 5:
gb->Interlace = check;
break;
}
break;
case 6: /* Chime */
switch (snum)
{ case 0: case 1: case 2:
if (check)
gb->Chime = snum;
break;
case 4:
gb->SmartHour = check;
break;
}
case 7: /* Alarm */
switch (snum)
{
case 0:
if (gb->AlarmWin.Win == NULL)
{
gb->St = gb->AlStd; tt[0] = &tags[0];
p = (ULONG *)tt[0];
*p++ = GTSL_Level; *p++ = gb->AlStd;
*p++ = GTSL_LevelFormat; *p++ = (ULONG)"%2ld";
*p++ = TAG_MORE; *p = (ULONG)&AlarmGadTags1[0];
gb->Mi = gb->AlMin; tt[1] = &tags[3];
p = (ULONG *)tt[1];
*p++ = GTSL_Level; *p++ = gb->AlMin;
*p++ = GTSL_LevelFormat; *p++ = (ULONG)"%2ld";
*p++ = TAG_MORE; *p = (ULONG)&AlarmGadTags2[0];
tt[2] = NULL; tt[3] = NULL;
CreateRequest(&gb->AlarmWin,(struct wInfo *)&AlarmWinInfo[0],&tt[0]);
}
break;
case 1:
gb->Alarm = check;
break;
}
break;
case 8: /* UseImage */
if (!(gb->UseImage=check))
OnMenu(gb->MainWin,FULLMENUNUM(3,NOITEM,NOSUB));
else
OffMenu(gb->MainWin,FULLMENUNUM(3,NOITEM,NOSUB));
break;
case 9: /* CloseGadget */
gb->CloseGad = check;
break;
case 11: /* Save Settings */
SaveSettings();
break;
}
break;
case 2: /* Colours */
case 3: /* Pattern */
if (gb->ColorWin.Win == NULL)
{
gb->Color = (mnum == 2 ? &gb->Pens[inum] : &gb->Must[inum]);
tt[0] = &tags[0];
p = (ULONG *)tt[0];
*p++ = GTPA_Depth; *p++ = gb->BitMap1.Depth; *p = TAG_DONE;
CreateRequest(&gb->ColorWin,(struct wInfo *)&ColorWinInfo[0],&tt[0]);
}
break;
}
}
NewSize1();
if ((gb->EndAll=NewSize2()))
return;
Rahmen();
ZifferBlatt();
Zeichnen();
}
/***************************************************************************/
/* */
/* resize invisible gadgets, init hidden drawing area */
/* */
/***************************************************************************/
CONST WORD Sizes[][4] = { /* Für Gadgets */
{ 0, 0, 3, 2 },
{ -3, 0, 3, 2 },
{ -3,-2, 3, 2 },
{ 0, 2, 0,-4 }
};
LONG NewSize2()
{ struct Window *win;
struct Gadget *gad;
PLANEPTR *p;
LONG tmp,w,w2,h,h2,bc,ret;
WORD i,j,k,newsize,*s;
bc = gb->BorderCount;
tmp = bc; if (gb->HiRes) tmp += (bc==2)<<1;
gb->BoLeft = tmp;
tmp = bc; if (gb->Interlace) tmp += (bc==2)<<1;
gb->BoTop = tmp;
win = gb->MainWin;
w = win->Width; gb->Width = w;
h = win->Height; gb->Height = h;
w2 = w-(gb->BoLeft<<1); gb->Width2 = w2;
h2 = h-(gb->BoTop<<1); gb->Height2 = h2;
gb->xDouble = (gb->xMask == -2 && w2 > 12);
gb->yDouble = (gb->yMask == -2 && h2 > 12);
tmp = 0; if (w2 > 25) tmp = (w2 > 50 ? 2 : 1);
gb->xOffset = tmp;
tmp = 0; if (h2 > 25) tmp = (h2 > 50 ? 2 : 1);
gb->yOffset = tmp;
tmp = w; if (w > h) tmp = h; newsize = tmp/8;
if (gb->GadSize != newsize)
{ gb->GadSize = newsize;
RemoveGList(gb->MainWin,&gb->GadgetBuf[0],-1);
for (gad=&gb->GadgetBuf[0],s=(WORD *)&Sizes[0],i=GB_GADCOUNT-1; i>=0; gad++,i--)
for (j=4-1,k=2; j>=0; k++,j--)
((UWORD *)gad)[k] = *s++*gb->GadSize;
AddGList(gb->MainWin,&gb->GadgetBuf[0],0,4,NULL);
}
InitBitMap(&gb->BitMap1,PUB_SCREEN->BitMap.Depth,gb->Width2,gb->Height2);
ret = 1;
for(p=&gb->BitMap1.Planes[0],i=gb->BitMap1.Depth; i!=0; i--)
if ((*p++=AllocRaster(gb->Width2,gb->Height)) == NULL)
return ret;
InitRastPort(&gb->RPort2); gb->RPort2.BitMap = &gb->BitMap1;
if ((gb->Buf=AllocRaster(gb->Width2,gb->Height)) != NULL)
{
gb->RPort2.TmpRas = InitTmpRas(&gb->TempRas,gb->Buf,RASSIZE(gb->Width2,gb->Height));
InitArea(&gb->AreaInfo,&gb->Table[0],5);
gb->RPort2.AreaInfo= &gb->AreaInfo;
ret = 0;
}
return ret;
}
/***************************************************************************/
/* */
/* issue a timer request */
/* */
/***************************************************************************/
ULONG NextTick()
{ struct timerequest *treq = gb->TimerIO;
ULONG tmp,old,std,min,sec;
treq->tr_node.io_Command = TR_GETSYSTIME;
DoIO(&treq->tr_node);
treq->tr_time.tv_micro = 1100000-treq->tr_time.tv_micro;
/* ^ Ein ganz besonders netter Effekt: Das Timer */
/* Device rundet aktuelle Zeit und Wartezeit ab */
sec = treq->tr_time.tv_secs;
tmp = 0; if (!gb->Seconds) tmp = 59-sec%60;
treq->tr_time.tv_secs = tmp;
treq->tr_node.io_Command = TR_ADDREQUEST;
SendIO(&treq->tr_node);
gb->TimerSent = -1;
old=gb->Min;
min=sec/60;
gb->Sec=sec%60;
std=min/12;
gb->Min=(min%=60);
gb->Std=std%60;
return (min-old); /* sec==0 ist unzuverlässig bei hoher CPU-Auslastung */
}
/***************************************************************************/
/* */
/* draw border */
/* */
/***************************************************************************/
VOID Rahmen()
{ struct RastPort *rp = gb->RPort1;
ULONG pen,pen11,pen12;
LONG w,h,bl,bt;
if (gb->BorderCount)
{
w = gb->Width; h = gb->Height;
pen11 = gb->Pens[11]; pen12 = gb->Pens[12];
if (gb->Active && gb->BorderCount == 1)
{
pen=pen11; pen11=pen12; pen12=pen;
}
SetAPen(rp,pen11);
Move(rp,1 ,h-1);
Draw(rp,w-1,h-1);
Draw(rp,w-1,1 );
SetAPen(rp,pen12);
Move(rp,0 ,h-1);
Draw(rp,0 ,0 );
Draw(rp,w-1,0 );
if (gb->BorderCount == 2)
{
bl = gb->BoLeft; bt = gb->BoTop;
SetAPen(rp,gb->Pens[12]);
Move(rp,bl ,h-bt);
Draw(rp,w-bl,h-bt);
Draw(rp,w-bl,bt );
SetAPen(rp,gb->Pens[11]);
Move(rp,bl-1,h-bt);
Draw(rp,bl-1,bt-1);
Draw(rp,w-bl,bt-1);
pen = gb->Pens[10]; if (gb->Active) pen = gb->Pens[13];
SetAPen(rp,pen);
if (gb->HiRes)
{
RectFill(rp,1,1,2,h-2);
RectFill(rp,w-3,1,w-2,h-2);
}
if (gb->Interlace)
{
RectFill(rp,1,1,w-2,2);
RectFill(rp,1,h-3,w-2,h-2);
}
}
}
SetAPen(rp,gb->Pens[0]);
}
/***************************************************************************/
/* */
/* create the clock */
/* */
/***************************************************************************/
CONST BYTE sinus[] = { /* sinus-Tabelle */
0,13,26,39,52,64,75,85,94,103,110,116,121,124,126,
127,126,124,121,116,110,103,94,85,75,64,52,39,26,13,
0,-13,-26,-39,-52,-64,-75,-85,-94,-103,-110,-116,-121,-124,-126,
-127,-126,-124,-121,-116,-110,-103,-94,-85,-75,-64,-52,-39,-26,-13
},
cosinus[] = { /* cosinus-Tabelle */
127,126,124,121,116,110,103,94,85,75,64,52,39,26,13,
0,-13,-26,-39,-52,-64,-75,-85,-94,-103,-110,-116,-121,-124,-126,
-127,-126,-124,-121,-116,-110,-103,-94,-85,-75,-64,-52,-39,-26,-13,
0,13,26,39,52,64,75,85,94,103,110,116,121,124,126
};
CONST BYTE srect[] = { /* Für rechteckiges Zifferblatt */
0,13,27,41,57,73,92,111,124,127,127,127,127,127,127,
127,127,127,127,127,127,127,124,111,92,73,57,41,27,13,
0,-13,-27,-41,-57,-73,-92,-111,-124,-127,-127,-127,-127,-127,-127,
-127,-127,-127,-127,-127,-127,-127,-124,-111,-92,-73,-57,-41,-27,-13
},
crect[] = {
127,127,127,127,127,127,127,124,111,92,73,57,41,27,13,
0,-13,-27,-41,-57,-73,-92,-111,-124,-127,-127,-127,-127,-127,-127,
-127,-127,-127,-127,-127,-127,-127,-124,-111,-92,-73,-57,-41,-27,-13,
0,13,27,41,57,73,92,111,124,127,127,127,127,127,127
};
CONST UBYTE pent[] = { /* Pen-Tabelle f. Zifferblatt */
6,8,8,7,8,8,7,8,8,7,8,8
};
CONST BYTE dx1[] = { /* Daten für Zifferblatt */
-2, 2, 1,-2, 1, 2,-2,-2,-1,-2,-1,-2
},
dy1[] = {
-4,-1,-2,-2, 2, 1,-2, 1, 2,-2,-2,-1
},
dx2[] = {
4,-2, 1, 4, 1,-2, 4, 2,-1, 4,-1, 2
},
dy2[] = {
0, 3, 2, 0,-2,-3, 0,-3,-2, 0, 2, 3
},
dx3[] = {
0,-2,-3, 0,-3,-2, 0, 2, 3, 0, 3, 2
},
dy3[] = {
8,-1, 2, 4,-2, 1, 4, 1,-2, 4, 2,-1
},
dx4[] = {
-4, 2,-1,-4,-1, 2,-4,-2, 1,-4, 1,-2
},
dy4[] = {
0,-3,-2, 0, 2, 3, 0, 3, 2, 0,-2,-3
};
VOID ZifferBlatt()
{ struct RastPort *rp = &gb->RPort2;
LONG i,a,b,c,x,y,bt,bl;
if (gb->BFInfo.BitMap && gb->UseImage)
{
CopyTiledBitMap(gb->BFInfo.BitMap,
gb->BFInfo.BitMapHeader->bmh_Width,
gb->BFInfo.BitMapHeader->bmh_Height,
&gb->BitMap1,gb->Width2,gb->Height2);
}
else
{
BNDRYOFF (rp);
SetAPen (rp,-1);
SetAfPt (rp,&gb->Muster[0][0],-1);
RectFill (rp,0,0,gb->Width2-1,gb->Height2-1);
SetAfPt (rp,0,0);
}
i = gb->Show; a = (i > 1 ? (i == 3 ? 60 : 15) : (i ? 5 : 1));
if (i < 4)
for (i=0; i<60; i+=a)
{ x = gb->Width2 /2 + (((gb->Oval ? sinus[i] : srect[i])*gb->Width2 /300) & gb->xMask);
y = gb->Height2/2 - (((gb->Oval ? cosinus[i] : crect[i])*gb->Height2/300) & gb->yMask);
if (i%5)
{ if (i%5==1)
{ c=gb->Pens[9];
SetAPen(rp,c);
SetOPen(rp,c);
}
AreaMove (rp,x+gb->Width2/200,y);
AreaDraw (rp,x,y+gb->Height2/200);
AreaDraw (rp,x-gb->Width2/200,y);
AreaDraw (rp,x,y-gb->Height2/200);
AreaEnd (rp);
}
else
{
b=i/5;
c=gb->Pens[pent[b]];
SetAPen(rp,c);
SetOPen(rp,c);
AreaMove (rp,x+=gb->Width2*dx1[b]/100,y+=gb->Height2*dy1[b]/100);
AreaDraw (rp,x+=gb->Width2*dx2[b]/100,y+=gb->Height2*dy2[b]/100);
AreaDraw (rp,x+=gb->Width2*dx3[b]/100,y+=gb->Height2*dy3[b]/100);
AreaDraw (rp,x+=gb->Width2*dx4[b]/100,y+=gb->Height2*dy4[b]/100);
AreaEnd (rp);
}
}
if (gb->Shadow)
{ Zeiger(gb->Std,440,1,gb->Pens[5],gb->Pens[5]);
Zeiger(gb->Min,300,1,gb->Pens[5],gb->Pens[5]); }
Zeiger(gb->Std,440,0,gb->Pens[3],gb->Pens[4]);
Zeiger(gb->Min,300,0,gb->Pens[1],gb->Pens[2]);
bl = gb->BoLeft;
gb->ReDrawx1 = bl; gb->ReDrawx2 = bl + gb->Width2 -1;
bt = gb->BoTop;
gb->ReDrawy1 = bt; gb->ReDrawy2 = bt + gb->Height2-1;
}
/*
** create hands
*/
CONST LONG HandWidth[] = {
4000,3250,2500,1750,1000
};
VOID Zeiger(ULONG winkel,LONG lfactor,LONG offset,LONG apen,LONG open)
{ struct RastPort *rp;
LONG x0,y0,x1,y1,x2,y2,tmp;
tmp = gb->Width2;
x2 = sinus [winkel]*tmp/lfactor;
x1 = cosinus[winkel]*tmp/HandWidth[gb->HandWidth];
x0 = tmp/2 + (offset ? gb->xOffset : 0);
tmp = gb->Height2;
y2 = cosinus[winkel]*tmp/lfactor;
y1 = sinus [winkel]*tmp/HandWidth[gb->HandWidth];
y0 = tmp/2 + (offset ? gb->yOffset : 0);
rp = &gb->RPort2;
SetAPen(rp,apen);
SetOPen(rp,open);
switch (gb->HandType)
{ case 0:
SetAPen(rp,open);
Move (rp,x0,y0);
Draw (rp,x0+x2,y0-y2);
if (gb->xDouble)
{ Move (rp,1+x0,y0);
Draw (rp,1+x0+x2,y0-y2); }
if (gb->yDouble)
{ Move (rp,x0,1+y0);
Draw (rp,x0+x2,1+y0-y2); }
break;
case 1:
AreaMove (rp,x0+x2 ,y0-y2 );
AreaDraw (rp,x0+x1-x2/4,y0+y1+y2/4);
AreaDraw (rp,x0-x1-x2/4,y0-y1+y2/4);
AreaEnd (rp);
break;
case 2:
AreaMove (rp,x0+x2 ,y0-y2 );
AreaDraw (rp,x0+x1 ,y0+y1 );
AreaDraw (rp,x0-x2/4,y0+y2/4);
AreaDraw (rp,x0-x1 ,y0-y1 );
AreaEnd (rp);
break;
case 3:
AreaMove (rp,x0+=x2-x1/2,y0-=y2+y1/2);
AreaDraw (rp,x0+=x1 ,y0+=y1 );
AreaDraw (rp,x0-=x2*5/4 ,y0+=y2*5/4 );
AreaDraw (rp,x0-=x1 ,y0-=y1 );
AreaEnd (rp);
break;
}
}
/***************************************************************************/
/* */
/* display the clock (blit from the `hidden' window to real one) */
/* */
/***************************************************************************/
VOID Zeichnen()
{ struct RastPort *rp = gb->RPort1;
LONG tmp,x1,y1,x2,y2;
BltBitMapRastPort(&gb->BitMap1,gb->ReDrawx1-gb->BoLeft,gb->ReDrawy1-gb->BoTop,
rp,gb->ReDrawx1,gb->ReDrawy1,gb->ReDrawx2-gb->ReDrawx1+1,
gb->ReDrawy2-gb->ReDrawy1+1,0xc0);
if (gb->Seconds)
{
x1 = gb->Width/2;
x2 = x1+sinus[gb->Sec]*gb->Width2/300;
y1 = gb->Height/2;
y2 = y1-cosinus[gb->Sec]*gb->Height2/300;
Move(rp,x1,y1);
Draw(rp,x2,y2);
if (gb->xDouble)
{ Move(rp,x1+1,y1);
Draw(rp,x2+1,y2); }
if (gb->yDouble)
{ Move(rp,x1,y1+1);
Draw(rp,x2,y2+1); }
if (x1 > x2)
{ tmp=x1; x1=x2; x2=tmp; }
if (gb->xDouble)
x2++;
gb->ReDrawx1 = x1; gb->ReDrawx2 = x2;
if (y1 > y2)
{ tmp=y1; y1=y2; y2=tmp; }
if (gb->yDouble)
y2++;
gb->ReDrawy1 = y1; gb->ReDrawy2 = y2;
}
}
/***************************************************************************/
/* */
/* initialize background pattern mask */
/* */
/***************************************************************************/
VOID SetPattern()
{ LONG i,a,b,c,d;
UBYTE *p1;
UWORD *p2;
p1=&gb->Must[0]; a=*p1++; b=*p1++; c=*p1++; d=*p1;
if (a==b && c==d) /* nur horizontale Streifen */
gb->xMask = -1;
else
gb->xMask = -2;
if (a==c && b==d) /* nur vertikale Streifen */
gb->yMask = -1;
else
gb->yMask = -2;
for (p2=&gb->Muster[0][0],i=0; i<8; i++)
{ *p2=(a&1<<i?0x5555:0)|(b&1<<i?0xaaaa:0); p2++;
*p2=(c&1<<i?0x5555:0)|(d&1<<i?0xaaaa:0); p2++; }
}
/***************************************************************************/
/* */
/* save current settings to the programs icon */
/* */
/***************************************************************************/
enum {TT_TOP=0,TT_LEFT,TT_WIDTH,TT_HEIGHT,TT_SHOWFACE,TT_HANDTYPE,TT_HANDWIDTH,
TT_BORDERTYPE,TT_CHIME,TT_SECONDS,TT_OVAL,TT_SHADOW,TT_CLOSEGAD,TT_USEIMAGE,
TT_DRAWPENS,TT_PATTERN};
CONST STRPTR ToolTypes[] = {
"TOP","LEFT","WIDTH","HEIGHT","SHOWFACE","HANDTYPE","HANDWIDTH","BORDERTYPE",
"CHIME","SECONDS","OVAL","SHADOW","CLOSEGAD","USEIMAGE","DRAWPENS","PATTERN"
};
#define TTCOUNT (sizeof(ToolTypes)/sizeof(ToolTypes[0]))
VOID SaveSettings()
{ struct DiskObject *dobj;
BPTR old_cd;
old_cd = CurrentDir(gb->ProgArg.wa_Lock);
if ((dobj=GetDiskObjectNew(gb->ProgArg.wa_Name)) != NULL) /* Tooltypes einlesen */
{
UBYTE **tt,*t,*tbuf,*tbuf1;
char **tmp,*p,**p1,**p2;
LONG arg,i;
p1=dobj->do_ToolTypes; p2=p1; do {} while(*p2++);
if ((tbuf=AllocVec(((STRPTR)p2-(STRPTR)p1)+sizeof(ToolTypes)+40*TTCOUNT,MEMF_ANY)))
{
tt=(UBYTE **)(tbuf+40*TTCOUNT);
p1=dobj->do_ToolTypes; p2=(char **)tt; do {} while((*p2++=*p1++));
for (i=0;i<TTCOUNT;i++) /* eigene Tooltypes entfernen */
{ if (FindToolType(tt,t=GetToolType(i)))
{ p2=(char **)tt; do {} while(*++p2 && FindToolType((UBYTE **)p2,t));
do { p=*p2++; } while((p2[-2]=p));
}
}
/* Tooltypes zählen */
p1=(char **)tt; do {} while(*p1++); --p1; tbuf1=tbuf;
*p1++=tbuf1;
tbuf1=SetToolType(tbuf1,"%s=%ld",TT_TOP,gb->MainWin->TopEdge);
*p1++=tbuf1;
tbuf1=SetToolType(tbuf1,"%s=%ld",TT_LEFT,gb->MainWin->LeftEdge);
*p1++=tbuf1;
tbuf1=SetToolType(tbuf1,"%s=%ld",TT_WIDTH,gb->Width);
*p1++=tbuf1;
tbuf1=SetToolType(tbuf1,"%s=%ld",TT_HEIGHT,gb->Height);
*p1++=tbuf1;
tbuf1=SetToolType(tbuf1,"%s=%ld",TT_SHOWFACE,gb->Show);
*p1++=tbuf1;
tbuf1=SetToolType(tbuf1,"%s=%ld",TT_HANDTYPE,gb->HandType);
*p1++=tbuf1;
tbuf1=SetToolType(tbuf1,"%s=%ld",TT_HANDWIDTH,gb->HandWidth);
*p1++=tbuf1;
arg = gb->BorderCount + (gb->HiRes ? 4 : 0) + (gb->Interlace ? 8 : 0);
tbuf1=SetToolType(tbuf1,"%s=%ld",TT_BORDERTYPE,arg);
*p1++=tbuf1;
arg = gb->Chime + (gb->SmartHour ? 4 : 0);
tbuf1=SetToolType(tbuf1,"%s=%ld",TT_CHIME,arg);
if (gb->Seconds)
{ *p1++=tbuf1; tbuf1=SetToolType(tbuf1,"%s",TT_SECONDS); }
if (gb->Oval)
{ *p1++=tbuf1; tbuf1=SetToolType(tbuf1,"%s",TT_OVAL); }
if (gb->Shadow)
{ *p1++=tbuf1; tbuf1=SetToolType(tbuf1,"%s",TT_SHADOW); }
if (gb->CloseGad)
{ *p1++=tbuf1; tbuf1=SetToolType(tbuf1,"%s",TT_CLOSEGAD); }
if (gb->UseImage)
{ *p1++=tbuf1; tbuf1=SetToolType(tbuf1,"%s",TT_USEIMAGE); }
*p1++=tbuf1;
tbuf1=SetToolType(tbuf1,"%s=x",TT_DRAWPENS); tbuf1=SetStr(tbuf1,&gb->Pens[0],14);
*p1++=tbuf1;
tbuf1=SetToolType(tbuf1,"%s=x",TT_PATTERN); tbuf1=SetStr(tbuf1,&gb->Must[0],4);
*p1=NULL;
tmp=dobj->do_ToolTypes;
dobj->do_ToolTypes=(char **)tt;
PutDiskObject(gb->ProgArg.wa_Name,dobj);
dobj->do_ToolTypes=tmp;
FreeVec(tbuf);
}
FreeDiskObject(dobj);
}
CurrentDir(old_cd);
}
/*
** make a tooltype string
*/
CONST ULONG tricky=0x16c04e75; /* move.b d0,(a3)+ ; rts */
STRPTR SetToolType(STRPTR buf,STRPTR fmt,LONG num,...)
{
((STRPTR *)&num)[0] = GetToolType(num);
RawDoFmt(fmt,(APTR)&num,(void (*)())&tricky,buf);
return (buf+=strlen(buf)+1);
}
/*
** get a tooltype name
*/
STRPTR GetToolType(LONG num)
{
return (STRPTR)ToolTypes[num];
}
/*
** make an ascii pen-string
*/
STRPTR SetStr(STRPTR dst,STRPTR src,LONG cnt)
{
--dst;
do
{ *dst++=DtoX(*src>>4);
*dst++=DtoX(*src++&0xf);
} while (--cnt);
*dst++='\0'; return dst;
}
LONG DtoX(LONG a)
{ if ((a+='0')>('9'))
a+=7;
return(a);
}
/***************************************************************************/
/* */
/* audio stuff */
/* */
/***************************************************************************/
CONST UWORD AlarmTune[] = {
800,800,800,800,800,800,800,1600,
800,800,800,800,800,800,800,1600,
800,800,800,800,800,800,800,1600,
800,800,800,800,800,800,800,1600,
800,800,800,800,800,800,800,4,0
};
CONST UWORD HourTune[] = {
800,1600,800,1600,800,1600,800,1600,
800,1600,800,1600,800,1600,800,1600,
800,1600,800,1600,800,1600,800,4,0
};
CONST UWORD QuarterTune[] = {
400,400,400,400,400,4,0
};
VOID TestIfAlarm()
{ CONST UWORD *tune;
ULONG st2;
LONG mi2,i;
st2=gb->Std; mi2 = gb->Min;
if (!(st2/=5))
st2=12;
tune = AlarmTune;
if (!gb->Alarm || mi2!=gb->AlMin || st2!=gb->AlStd)
{ if (!gb->Chime)
return;
if (!mi2)
{
tune = HourTune; i=22; if (gb->SmartHour) i=24-st2;
}
else
{ if (gb->Chime != 2)
return;
tune = QuarterTune;
for(i=6;;)
{ i-=2;
if ((mi2-=15)<0)
return;
if (mi2==0)
break;
}
}
tune = &tune[i];
}
StartTune(tune);
}
/*
** allocate audio channels and initiate the sound
*/
CONST UBYTE ChannelMap[] = { 1,2,4,8 }; /* Sound Channel Allocation Map */
VOID StartTune(CONST UWORD *tune)
{ struct IOAudio *io;
if (!gb->SoundOn)
{
io = gb->AudioIO[0];
io->ioa_Request.io_Command = ADCMD_ALLOCATE;
io->ioa_Request.io_Message.mn_Node.ln_Pri = 90; /* ALARM-Level */
io->ioa_Request.io_Flags = ADIOF_NOWAIT;
io->ioa_Data = (UBYTE *)&ChannelMap[0];
io->ioa_Length = sizeof(ChannelMap);
BeginIO(&io->ioa_Request);
if (!WaitIO(&io->ioa_Request))
{
gb->SoundOn = -1;
if (!(ciaa.ciapra & CIAF_LED))
{
ciaa.ciapra |= CIAF_LED; gb->Filter = -1;
}
CopyMemQuick(io,gb->AudioIO[1],sizeof(struct IOAudio));
gb->PlayTune = (UWORD *)tune;
PlayNote();
PlayNote();
}
}
}
/*
** beep, beep, ...
*/
VOID PlayNote()
{ struct IOAudio *io;
LONG old,new;
BYTE *sent = &gb->AudioSent[0];
old = gb->RequestNr;
new = !old;
gb->RequestNr = new;
sent[old] = 0;
if (!*gb->PlayTune)
{ if (!sent[new]) /* Anderer Request auch zurück ? */
EndTune(); return; }
sent[old] = -1; /* Merken */
io = gb->AudioIO[old];
io->ioa_Request.io_Command = CMD_WRITE;
io->ioa_Request.io_Flags = ADIOF_PERVOL;
io->ioa_Data = (UBYTE *)&((ULONG *)gb->WaveForm)[old];
io->ioa_Length = 4;
io->ioa_Period = 500; /* ekliger Piepton */
io->ioa_Volume = 64;
io->ioa_Cycles = *(gb->PlayTune)++;
BeginIO(&io->ioa_Request);
}
/*
** end audio output
*/
VOID EndTune()
{ struct IOAudio *ioreq = gb->AudioIO[0];
ioreq->ioa_Request.io_Command=ADCMD_FREE;
DoIO(&ioreq->ioa_Request);
if (gb->Filter)
{
ciaa.ciapra &= ~CIAF_LED; gb->Filter = 0;
}
gb->SoundOn = 0;
}
/***************************************************************************/
/* */
/* create a new window and its gadgets */
/* */
/***************************************************************************/
CONST struct TextAttr Topaz = {
"topaz.font",8,FS_NORMAL,FPF_ROMFONT
};
VOID CreateRequest(struct WinGad *wg,struct wInfo *wi,struct TagItem **tagptr)
{ struct Gadget *context;
if ((context=CreateContext(&wg->Gad)) != NULL)
{
struct NewWindow *nw = &gb->NewWindowBuf;
struct Window *win;
struct gInfo *gi;
UWORD cnt;
nw->LeftEdge = 100;
nw->TopEdge = 100;
nw->Width = 0;
nw->Height = 0;
nw->Flags = WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_ACTIVATE|WFLG_RMBTRAP;
nw->FirstGadget = wg->Gad;
nw->Title = GetCatalogString(wi->textnr);
gb->NewGad.ng_GadgetID = 0; cnt = wi->gadcnt; gi = &wi->gi[0];
do
{ struct NewGadget *ng = &gb->NewGad;
struct Screen *scr = gb->MainWin->WScreen;
ULONG num;
ng->ng_LeftEdge = gi->left + scr->WBorLeft;
ng->ng_TopEdge = gi->top + scr->WBorLeft + scr->RastPort.TxHeight;
ng->ng_Width = gi->width;
ng->ng_Height = gi->height;
if ((num=gi->textnr))
num = (ULONG)GetCatalogString(num);
ng->ng_GadgetText = (STRPTR)num;
ng->ng_TextAttr = (struct TextAttr *)&Topaz;
ng->ng_GadgetID++;
ng->ng_VisualInfo = gb->VisualInfo;
if ((context=CreateGadgetA(gi->kind,context,ng,tagptr[0])) == NULL)
{
FreeGadgets(wg->Gad); wg->Gad = NULL; return;
}
gi++; tagptr++;
} while(--cnt);
if ((wg->Win=(win=OpenWindowShared(&gb->NewWindowBuf,&WindowTags[0],wi->idcmp))) != NULL)
{
SetWindowTitles(win,(UBYTE *)-1L,PROGNAME); GT_RefreshWindow(win,NULL);
}
else
{
FreeGadgets(wg->Gad); wg->Gad = NULL;
}
}
}
/***************************************************************************/
/* */
/* open a window for shared IDCMP */
/* */
/***************************************************************************/
struct Window *OpenWindowShared(struct NewWindow *nw,CONST struct TagItem *tl,ULONG idcmp)
{ struct Window *win;
if ((win=OpenWindowTagList(nw,(struct TagItem *)tl)) != NULL)
{
win->UserPort = gb->WindowPort;
if (!ModifyIDCMP(win,idcmp))
{
CloseWindowSafely(win); win=NULL;
}
}
return win;
}
/***************************************************************************/
/* */
/* get localized string */
/* */
/***************************************************************************/
CONST STRPTR LocStrings[] = {
/* MSG_PROJECT */ "Project",
/* MSG_ABOUT */ "About",
/* MSG_ABOUTKEY */ "?",
/* MSG_QUIT */ "Quit",
/* MSG_QUITKEY */ "Q",
/* MSG_SETTINGS */ "Settings",
/* MSG_SECONDS */ "Seconds",
/* MSG_OVAL */ "Oval",
/* MSG_SHOW */ "show",
/* MSG_MINUTES */ "Minutes",
/* MSG_HOURS */ "Hours",
/* MSG_QUARTER */ "Quarter",
/* MSG_ONE */ "One",
/* MSG_NONE */ "None",
/* MSG_HANDS */ "Hands",
/* MSG_LINE */ "Line",
/* MSG_TRIANGLE */ "Triangle",
/* MSG_RHOMBUS */ "Rhombus",
/* MSG_RECTANGLE */ "Rectangle",
/* MSG_VERYTHIN */ "Very Thin",
/* MSG_THIN */ "Thin",
/* MSG_NORMAL */ "Normal",
/* MSG_THICK */ "Thick",
/* MSG_VERYTHICK */ "Very Thick",
/* MSG_SHADOW */ "Shadow",
/* MSG_BORDER */ "Border",
/* MSG_SINGLE */ "Single",
/* MSG_DOUBLE */ "Double",
/* MSG_HIRES */ "HiRes",
/* MSG_INTERLACE */ "Interlace",
/* MSG_CHIME */ "Chime",
/* MSG_SMART */ "Smart",
/* MSG_ALARM */ "Alarm",
/* MSG_SET */ "Set",
/* MSG_ON */ "On",
/* MSG_USEIMAGE */ "Use Image",
/* MSG_CLOSEGAD */ "Close Gadget",
/* MSG_SAVESETTING */ "Save Settings",
/* MSG_SAVEKEY */ "S",
/* MSG_COLORS */ "Colors",
/* MSG_MINAPEN */ "Min. APen",
/* MSG_MINOPEN */ "Min. OPen",
/* MSG_HOURAPEN */ "Hour Apen",
/* MSG_HOUROPEN */ "Hour Open",
/* MSG_STR12 */ "12",
/* MSG_BORDER0 */ "Border 0",
/* MSG_BORDER1 */ "Border 1",
/* MSG_BORDER2 */ "Border 2",
/* MSG_BORDER3 */ "Border 3",
/* MSG_PATTERN */ "Pattern",
/* MSG_COLOR0 */ "Color 0",
/* MSG_COLOR1 */ "Color 1",
/* MSG_COLOR2 */ "Color 2",
/* MSG_COLOR3 */ "Color 3",
/* MSG_DESCRIPTION */ "a really nice clock !",
/* MSG_CHOOSE */ "Choose one:",
/* MSG_USE */ "Use",
/* MSG_CANCEL */ "Cancel"
};
STRPTR GetCatalogString(LONG strnum)
{ struct Catalog *cat;
STRPTR loc;
loc = LocStrings[strnum];
if ((cat=gb->Catalog) != NULL)
loc = GetCatalogStr(cat,strnum,loc);
return loc;
}
/***************************************************************************/
/* */
/* duplicate a bitmap (based on the work of P.Carette + W.Dörwald) */
/* */
/***************************************************************************/
VOID CopyTiledBitMap(struct BitMap *Src,LONG SrcSizeX,LONG SrcSizeY,struct BitMap *Dst,LONG DstSizeX,LONG DstSizeY)
{ LONG Pos; /* used as starting position in the "exponential" blit */
LONG Size; /* used as bitmap size in the "exponential" blit */
/* blit the first piece of the tile */
blt_bitmap(Src,0,0,Dst,0,0,MIN(SrcSizeX,DstSizeX),MIN(SrcSizeY,DstSizeY),0xC0,-1,NULL);
/* this loop generates the first row of the tiles */
for (Pos = SrcSizeX,Size = MIN(SrcSizeX,DstSizeX-Pos);Pos<DstSizeX;)
{
blt_bitmap(Dst,0,0,Dst,Pos,0,Size,MIN(SrcSizeY,DstSizeY),0xC0,-1,NULL);
Pos += Size;
Size = MIN(Size<<1,DstSizeX-Pos);
}
/* this loop blit the first row down several times to fill the whole dest rect */
for (Pos = SrcSizeY,Size = MIN(SrcSizeY,DstSizeY-Pos);Pos<DstSizeY;)
{
blt_bitmap(Dst,0,0,Dst,0,Pos,DstSizeX,Size,0xC0,-1,NULL);
Pos += Size;
Size = MIN(Size<<1,DstSizeY-Pos);
}
}
/***************************************************************************/
/* */
/* replacement functions */
/* */
/***************************************************************************/
Object *new_dt_object(APTR name, ULONG data, ...)
{
return NewDTObjectA(name,(struct TagItem *)&data);
}
ULONG get_dt_attrs(Object *obj, ULONG data, ...)
{
return GetDTAttrsA(obj,(struct TagItem *)&data);
}
LONG blt_bitmap(struct BitMap *src,LONG xsrc,LONG ysrc,struct BitMap *dst,
LONG xdst,LONG ydst,LONG xsize,LONG ysize,ULONG minterm,
ULONG mask,PLANEPTR tempA)
{
return BltBitMap(src,xsrc,ysrc,dst,xdst,ydst,xsize,ysize,minterm,mask,tempA);
}
/***************************************************************************/
/* */
/* The End */
/* */
/***************************************************************************/